package com.github.livebase.plugins;

import android.util.ArrayMap;
import android.util.Log;

import com.github.livebase.util.StringKeyValuePairs;
import com.github.livebase.util.base.CollectionsUtil;
import com.github.livebase.util.base.NumberUtil;
import com.github.livebase.util.base.ObjectsUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @ClassName Reader
 * @description:
 * @author: biao532
 * @create: 2023-12-30 18:41
 * @Version 1.0
 **/
public class MetaData {
    private String name;
    private int version;
    private int pluginVersion;
    private String dex;
    private String configDir;
    private Map<String, List<String>> registers;
    public MetaData(int defaultVer, ZipFile file) throws MateDataException {
        ZipEntry zipEntry = file.getEntry("main.inf");
        this.registers = new ArrayMap<>(6);
        if (null == zipEntry) {
            throw new MateDataException("无效的插件格式");
        }
        try(InputStream stream = file.getInputStream(zipEntry)) {
            read(stream);
            this.name = getFirst("name");
            remove("name");
            this.dex = getFirstOrDefault("dex", "dex.jar");
            remove("dex");
            this.version = NumberUtil.toInteger(getFirst("version"), defaultVer);
            remove("version");
            this.pluginVersion = NumberUtil.toInteger(getFirst("pluginVersion"), 1);
            remove("pluginVersion");
            this.configDir = getFirst("configDir");
            remove("configDir");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String getName() {
        return name;
    }

    public int getVersion() {
        return version;
    }

    public int getPluginVersion() {
        return pluginVersion;
    }

    public String getDex() {
        return dex;
    }

    public List<String> get(String key) {
        return registers.get(key.toLowerCase(Locale.ROOT));
    }

    public Map<String, List<String>> getRegisters() {
        return registers;
    }

    public List<String> getOrDefault(String key, List<String> defaultVal) {
        return ObjectsUtil.getOrDefault(get(key), defaultVal);
    }

    public String getConfigDir() {
        return this.configDir;
    }

    public String getFirst(String key) {
        return CollectionsUtil.getOrDefault(get(key), 0, null);
    }
    public String getFirstOrDefault(String key, String defaultVal) {
        return ObjectsUtil.getOrDefault(getFirst(key), defaultVal);
    }

    private List<String> remove(String key) {
        return this.registers.remove(key.toLowerCase(Locale.ROOT));
    }
    private void read(InputStream inputStream) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line = null;
        while ( (line = reader.readLine()) != null) {
            line = removeCommand(line);
            if (line.isEmpty()) {
                continue;
            }
            StringKeyValuePairs pairs = StringKeyValuePairs.createKeyValuePairs(line, "=");
            List<String> rs = this.registers.get(pairs.getKey());
            if (rs == null) {
                rs = new ArrayList<>();
                this.registers.put(pairs.getKey().toLowerCase(Locale.ROOT), rs);
            }
            if (!rs.contains(pairs.getValue())) {
                rs.add(pairs.getValue());
            }
        }
    }

    private String removeCommand(String line) {
        int idx = line.indexOf("#");
        if (idx != -1) {
            return line.substring(0, idx).trim();
        }
        return line.trim();
    }

    private boolean wrapperBy(String line, String prefix, String suffix) {
        if (line == null){
            return false;
        }
        if (line.length() < prefix.length() + suffix.length()) {
            return false;
        }
        return line.startsWith(prefix) && line.endsWith(suffix);
    }

    private String removeWrapper(String line, String prefix, String suffix) {
        if (wrapperBy(line, prefix, suffix)) {
            return line.substring(prefix.length(), suffix.length());
        }
        return null;
    }
}
